package com.cabal.module.log.interceptor;

import com.cabal.common.aliyunOSS.AliyunOSSUtil;
import com.cabal.common.enums.RequestMessageType;
import com.cabal.common.util.SnowflakeIdUtil;
import com.cabal.common.util.CabalJsonUtil;
import com.cabal.common.util.TmsServiceException;
import com.cabal.module.log.annotation.RequestMessageLogRecord;
import com.cabal.module.log.entity.RequestMessageLog;
import com.cabal.module.log.service.IRequestMessageLogService;
import com.cabal.module.web.HttpHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 报文拦截处理将报文存储在文件服务器目录，数据库记录基本信息用于查询展示
 *
 * @author shenkang
 * @data 2022年4月25日
 */
@Slf4j
@Component(value = "requestMessageLogInterceptor")
public class RequestMessageLogInterceptor implements HandlerInterceptor {

    @Autowired
    private IRequestMessageLogService requestMessageLogService;

    private final static String HTTP_REQUEST_MESSAGE_LOG = "httpRequestMessageLog/";

    private final static String FILE_TYPE_TXT = ".txt";

    /**
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class, noRollbackFor = TmsServiceException.class)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            if (!method.isAnnotationPresent(RequestMessageLogRecord.class)) {
                return true;
            }
        } else {
            return true;
        }

        try {
            String data = HttpHelper.getBodyString(request);
            if(StringUtils.isBlank(data)) {
                return false;
            }
            String path = request.getRequestURI();
            // 根据请求url判断消息类型
            RequestMessageType requestMessageType = RequestMessageType.getType(path);
            Long messageId = SnowflakeIdUtil.getInstance().nextId();
            RequestMessageLog requestMessageLog = new RequestMessageLog();
            if (requestMessageType != null && requestMessageType.getPath().equals("declaration")) {
                requestMessageLog.setIpAddress(request.getRemoteAddr())
                        .setAddressUrl(path)
                        .setId(messageId);
                Map<String,Object> mapResult = CabalJsonUtil.json2map(data);
                if(mapResult != null) {
                    requestMessageLog.setMessageType(mapResult.get("messageType").toString());
                }
            }

            // 将请求报文上传到OSS，文件名称为消息Id，上传完成后返回的OSS地址存入到数据库
            String ossPath = uploadRequestMessageLog(data, messageId);
            requestMessageLog.setFilePath(ossPath);
            requestMessageLogService.insertRequestMessageLog(requestMessageLog);
            request.setAttribute("messageId", messageId);
        }catch (Exception e){
            log.error("interceptor save message error:{}", e);
            if(e instanceof TmsServiceException){
                throw e;
            }
        }
        return true;
    }

    private String uploadRequestMessageLog(String data, Long messageId) {
        String fileName = HTTP_REQUEST_MESSAGE_LOG.concat(messageId.toString()).concat(FILE_TYPE_TXT);
        return AliyunOSSUtil.uploadByByte(fileName, data.getBytes());
    }
}
